<?php
/**
 * 制造
 * 
 * Created	: 2011-04-18
 * Modified : 2011-04-18
 * @author  : 陈立强
 */
class Making
{
	
	public static $cfg = null;
	public static $cfgName = 'build/making';

	
	/**
	 * 开启制造建筑信息
	 * @param int $uid
	 * @param int $class
	 */
	public static function open ($uid, $class)
	{
		global $DB, $L, $G;
		
		$class = (int)$class;
		
		if (!isset($G['make_class_type_sign_list'][$class])) {
			return array(
				'val' => false,
				'msg' => $L['product_type_not_exists']
			);
		}
		
		// 判断金钱是否足够
		$sql = 'SELECT coin FROM user WHERE uid='.$uid;
		$coin = $DB->getValue($sql);
		$needCoin = $G['make_building_lvlup_coin'][0];
		if ($needCoin > $coin) {
			return array(
				'val' => false,
				'msg' => $L['coin_not_enough']
			);
		}
		
		$sql = 'SELECT mkid FROM make_building WHERE uid='.(int)$uid.' and class='.(int)$class;
		$mk = $DB->getValue($sql);
		
		if ($mk) {
			return array(
				'val' => false,
				'msg' => $L['make_building_is_opened']
			);
		}
		
		$DB->beginTransaction();
		
		$data = array(
			'uid'			=> $uid,
			'class'			=> $class,
			'building_lvl'	=> 1,
		);
		$mkid = $ret = $DB->insert('make_building', $data);
		
		// 扣除金线
		if ($ret) {
			$sql = 'UPDATE user set coin=coin-'.$needCoin.' WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
		}
		
		if ($ret) {
			$DB->setTransactionState(false);
			$ret = Staff::add($uid, $class);
			$DB->setTransactionState(true);
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				'mkid'	=> $mkid,
				'sql'	=> $sql
			);
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('making_open', $str);
		}
		
		return $result;
	}
	
	/**
	 * 获取一个工坊建筑信息
	 * @param int $uid
	 * @param int $class 类型
	 */
	public static function getInfo($uid, $class=0, $moreInfo=true)
	{
		global $DB, $L, $G;
		
		$class = (int)$class;
		
		if (!isset($G['make_class_type_sign_list'][$class])) {
			return array(
				'val' => false,
				'msg' => $L['product_type_not_exists']
			);
		}
		
		$where = 'uid='.(int)$uid;
		if ($class) {
			$where .= ' and class='.$class;
		}
		$sql = 'SELECT * FROM make_building WHERE '.$where;
		if ($class) {
			$info  = $DB->getValue($sql);
		} else {
			$info = $DB->getList($sql);
		}
		if (false === $info) {
			return false;
		}
		
		if ($moreInfo) {
			$staffInfo = Staff::getInfo($uid, $class);
			$info['staff_id'] = $staffInfo['staff_id'];
			$info['staff_exp'] = $staffInfo['exp'];
			$info['potential_lvl'] = $staffInfo['potential_lvl'];
		}
		
		return $info;
	}
	
	/**
	 * 升级工坊相关建筑
	 * @param int $uid 用户ID
	 * @param int $class 类型
	 */
	public static function lvlUp($uid, $class)
	{
		global $DB, $L, $G;
		
		$class = (int)$class;
		
		if (!isset($G['make_class_type_sign_list'][$class])) {
			return array(
				'val' => false,
				'msg' => $L['product_type_not_exists']
			);
		}
		
		$info = self::getInfo($uid, $class, false);
		if (!$info) {
			return array(
				'val' => false,
				'msg' => $L['make_building_is_max_lvl']
			);
		}
		// 已经达到满级
		if ($info['building_lvl'] >= $G['make_building_max_lvl']) {
			return array(
				'val' => false,
				'msg' => $L['make_building_is_max_lvl']
			);
		}
		$nowLvl = $info['building_lvl'];
		// 判断经验是否足够
		if ($G['make_building_lvlup_exp'][$nowLvl] > $info['exp']) {
			return array(
				'val' => false,
				'msg' => $L['building_exp_not_enough']
			);
		}
		$info['building_lvl']	+= 1;
		$info['exp']			-= $G['make_building_lvlup_exp'][$nowLvl];
		
		// 判断金钱是否足够
		$sql = ' SELECT coin FROM user WHERE uid='.$uid;
		$coin = $DB->getValue($sql);
		if ($G['make_building_lvlup_coin'][$nowLvl] > $coin) {
			return array(
				'val' => false,
				'msg' => $L['coin_not_enough']
			);
		}
		
		$DB->beginTransaction();
		
		//-- 扣除金钱
		$sql = 'UPDATE user SET coin=coin-'.$G['make_building_lvlup_coin'][$nowLvl].' WHERE uid='.$uid;
		$ret = $DB->exeSql($sql);

		$data = array(
			'building_lvl'	=> $info['building_lvl'],
			'exp'			=> $info['exp']
		);
		$where = 'uid='.$uid.' and class='.$class;
		$ret = $DB->update('make_building', $data, $where);
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				'lvl' => $info['building_lvl']
			);
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('making_lvl_up', $str);
		}
		return $result;
	}
	
	/**
	 * 获取主材类型下拉列表
	 * @param int uid
	 * @param string $class cook-烹饪,drink-酒水,furniture-家具
	 */
	public static function getMainMatTypelist($uid, $class)
	{
		global $G;
		
		if (!isset($G['make_class_list'][$class])) {
			return array(
				'val' => false,
				'msg' => $L['product_type_not_exists']
			);
		}
		$list = C('making/main_mat_list_4_'.$class);
		if ($list) {
			return array(
				'val'	=> true,
				'data'	=> $list
			);
		} else {
			return array(
				'val'	=> false,
				'msg'	=> $L['invalid_request']
			);
		}
	}
	
	/**
	 * 获取所有配方的基础人气值总和
	 * @param $uid
	 */
	public static function getRecipeTotalPopVal($uid)
	{
		global $DB, $L, $G;
		
		$sql = 'SELECT product_lvl,lvl FROM make_recipe WHERE uid='.$uid;
		$list = $DB->getList($sql);
		
		$popVal = 0;
		foreach ($list as $v) {
			$cfg = $G['recipe'][$v['product_lvl']][$v['lvl']];
			$popVal += $cfg['pop_val'];
		}
		
		return $popVal;
	}
	
	/**
	 * 保存配方
	 * @param int $uid
	 * @param int $title 名称
	 * @param string $class 类型:烹饪,饮品,酿酒...(cook,drink..)
	 * @param int $product 产品:1-面食,2-糕点...
	 * @param int $technics 工艺
	 * @param int $param 参数:火力,温度,酒精浓度
	 * @param array $main_mat 主材
	 * @param array $sec_mat 辅材
	 */
	public static function saveRecipe($uid, $title, $class, $product, $technics, $param, $main_mat, $sec_mat, $recipe_id=0)
	{
		global $DB, $L, $G;
		
		$product	= (int)$product;
		$technics	= (int)$technics;
		$param		= (int)$param;
		$title		= trim($title);
		$recipe_id	= (int)$recipe_id;
		
		// 配方长度名不能太长
		mb_internal_encoding('utf-8');
		if (mb_strlen($title) > $G['recipe_title_len']) {
			return array(
				'val' => false,
				'msg' => $L['recipe_title_len_too_long']
			);
		}
		
		// 不能替换非自己的配方
		if ($recipe_id > 0){
			$sql = 'SELECT uid FROM make_recipe WHERE id='.$recipe_id;
			$_uid = $DB->getValue($sql);
			if ($_uid != $uid) {
				return array(
					'val' => false,
					'msg' => $L['invalid_request']
				);
			}
		}
		
		// 制造类型ID
		if (!isset($G['make_class_type_list'][$class])) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		$classId = $G['make_class_type_list'][$class];
		$sql = 'SELECT staff_id,max_recipe_num FROM staff WHERE uid='.$uid.' AND class='.$classId;
		$staff = $DB->getValue($sql);
		if (!$staff) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		$staff_id = $staff['staff_id'];
		
		// 配方拥有数量是否已满
		if (!$recipe_id) {
			$sql = 'SELECT COUNT(*) FROM make_recipe WHERE staff_id='.$staff_id;
			$totalNum = $DB->getValue($sql);
			if ($totalNum >= $staff['max_recipe_num']) {
				return array(
					'val' => false,
					'msg' => $L['make_recipe_num_reached_max']
				);
			}
		}
		
		
		// 制造产品
		if (!isset($G[$class][$product])) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		// 制造工艺
		if (!isset($G[$class.'_technics'][$technics])) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		// 其它参数:火力,温度...
		if (!isset($G[$class.'_param'][$param])) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		if (count($main_mat) != $G['main_mat_type_num']) {
			return array(
				'val' => false,
				'msg' => $L['main_mat_type_num_error'].count($main_mat).$G['main_mat_type_num']
			);
		}
		if (count($sec_mat) != $G['sec_mat_type_num']) {
			return array(
				'val' => false,
				'msg' => $L['sec_mat_type_num_error']
			);
		}
		
		$info = self::getInfo($uid, $classId, false);
		
		// 配方等级等于产品等级,等于数量最多的主材等级
		$productLvl = 0;
		$maxNum = 0;
		$itemList = C('item/item_list');
		$itemMat = C('making/'.$class.'_item_mat');
		$_tmpLvl = array();// 保存不同等级产品的种类数量
		foreach ($main_mat as $item_id) {
			if (!isset($itemList[$item_id]) || $item_id > 1000 || !isset($itemMat[$item_id])) {
				return array(
					'val' => false,
					'msg' => $L['item_is_not_main_mat']
				);
			}
			$itemCfg = $itemList[$item_id];
			// 材料等级不能超出建筑等级
			if ($info['building_lvl'] < $itemCfg['lvl']) {
				return array(
					'val'	=> false,
					'msg'	=> $L['main_mat_lvl_higher_than_building_lvl']
				);
			}
			if (!isset($_tmpLvl[$itemCfg['lvl']])) {
				$_tmpLvl[$itemCfg['lvl']] = 1;
			} else {
				$_tmpLvl[$itemCfg['lvl']] += 1;
			}
		}
		
		// 主材料4种,有4个记录,说明4个材料的等级不同,取最高等级
		if (count($_tmpLvl) == $G['main_mat_type_num']) {
			ksort($_tmpLvl);
			$productLvl = end($_tmpLvl);
		} else {
			$num = 0;
			foreach ($_tmpLvl as $lvl=>$cnt) {
				if ($cnt > $num) {
					$productLvl = $lvl;
					$num = $cnt;
				} else if ($cnt == $num && $lvl > $productLvl) {
					$productLvl = $lvl;
				}
			}
		}
		
		foreach ($sec_mat as $item_id) {
			if (!isset($itemMat[$item_id]) || !isset($itemList[$item_id])) {
				return array(
					'val' => false,
					'msg' => $L['item_is_not_sec_mat']
				);
			}
		}
		
		$DB->beginTransaction();
		
		$data = array(
			'uid'			=> $uid,
			'staff_id'		=> $staff_id,
			'title'			=> $title,
			'product_lvl'	=> $productLvl,
			'lvl'			=> 1,
			'exp'			=> 0,
			'class'			=> $classId,
			'product'		=> $product,
			'technics'		=> $technics,
			'param'			=> $param,
			'main_mat'		=> json_encode($main_mat),
			'sec_mat'		=> json_encode($sec_mat),
		);
		if ($recipe_id > 0){
			$where = 'id='.$recipe_id;
			$ret = $DB->update('make_recipe', $data, $where);
			$ret!==false && $ret =  true;
		} else {
			$ret = $DB->insert('make_recipe', $data);
		}
		
		// 判断人气值是否需要更新
		if ($ret) {
			$sql = 'SELECT pop_val FROM user_shop WHERE uid='.$uid;
			$pop_val = $DB->getValue($sql);
			$new_pop_val = self::getRecipeTotalPopVal($uid);
			if ($new_pop_val > $pop_val) {
				$sql = 'UPDATE user_shop SET pop_val='.$new_pop_val.' WHERE uid='.$uid;
				$ret = $DB->exeSql($sql);
			}
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$data['main_mat']	= $main_mat;
			$data['sec_mat']	= $sec_mat;
			$result['data']		= $data;
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('making_save_recipe', $str);
		}
		
		return $result;
	}
	
	/**
	 * 获取配方列表
	 * @param int $uid
	 * @param int $staff_id
	 */
	public static function getRecipeList($uid, $staff_id)
	{
		global $DB, $L, $G;
		
		$recipe_id = (int)$staff_id;
		
		$sql = 'SELECT * FROM make_recipe WHERE uid='.$uid.' AND staff_id='.$staff_id;
		$list = $DB->getList($sql);
		
		if (!$list) {
			return array (
				'val'	=> true,
				'data'	=> array(),
			);
		}
		
		$itemList = C('item/item_list');
		
		$matIdList = array();
		
		foreach ($list as $k=>$v) {
			$classSign = $G['make_class_type_sign_list'][$v['class']];
//			$list[$k]['class'] = $G['make_class_type_name_list'][$v['class']];
			$list[$k]['product'] = $G[$classSign][$v['product']]['title'];
			$list[$k]['technics'] = $G[$classSign.'_technics'][$v['technics']];
			$list[$k]['param'] = $G[$classSign.'_param'][$v['param']];
			$main_mat	= json_decode($v['main_mat'], true) ;
			$sec_mat	= json_decode($v['sec_mat'], true) ;
			$list[$k]['main_mat'] = array();
			$list[$k]['sec_mat'] = array();
			$list[$k]['exp'] = $v['exp'];
			foreach ($main_mat as $item_id) {
				if (!in_array($item_id, $matIdList)) {
					$matIdList[] = $item_id;
				}
				$itemCfg = $itemList[$item_id];
				$list[$k]['main_mat'][] = array(
					'item_id'	=> $item_id,
					'item_type'	=> $itemCfg['type'],
					'title'		=> $itemCfg['title']
				);
			}
			foreach ($sec_mat as $item_id) {
				if (!in_array($item_id, $matIdList)) {
					$matIdList[] = $item_id;
				}
				$itemCfg = $itemList[$item_id];
				$list[$k]['sec_mat'][] = array(
					'item_id'	=> $item_id,
					'item_type'	=> $itemCfg['type'],
					'title'		=> $itemCfg['title']
				);
			}
		}
		
		// 从数据库获取主/辅材数量
		$sql = 'SELECT item_id,num,quality FROM depot WHERE uid='.$uid.' AND item_id in ('.join(',', $matIdList).')';
		$matList = $DB->getList($sql);
		$matList2 = array();
		foreach ($matList as $v) {
			$matList2[$v['item_id'].','.$v['quality']] = $v['num'];
		}
		
		foreach ($list as $k=>$v) {
			if ($v['lvl'] > 3) {
				$quality = 3;
			} else {
				$quality = $v['lvl'];
			}
			foreach ($v['main_mat'] as $kk=>$vv) {
				$key = $vv['item_id'].','.$quality;
				if (!isset($matList2[$key])) {
					$list[$k]['main_mat'][$kk]['lack_num'] = $G['main_mat_num'];
					continue;
				}
				$holdNum = $matList2[$key];
				if ($G['main_mat_num'] > $holdNum) {
					$list[$k]['main_mat'][$kk]['lack_num'] = $G['main_mat_num'] - $holdNum;
				} else {
					$list[$k]['main_mat'][$kk]['lack_num'] = 0;
				}
			}
			foreach ($v['sec_mat'] as $kk=>$vv) {
				$key = $vv['item_id'].','.$quality;
				if (!isset($matList2[$key])) {
					$list[$k]['sec_mat'][$kk]['lack_num'] = $G['sec_mat_num'];
					continue;
				}
				$holdNum = $matList2[$key];
				if ($G['sec_mat_num'] > $holdNum) {
					$list[$k]['sec_mat'][$kk]['lack_num'] = $G['sec_mat_num'] - $holdNum;
				} else {
					$list[$k]['sec_mat'][$kk]['lack_num'] = 0;
				}
			}
		}
		
		
		return array (
			'val'	=> true,
			'data'	=> $list,
		);
	}
	
	
	/**
	 * 删除配方
	 * @param int $uid
	 * @param int $recipe_id
	 */
	public static function deleteRecipe($uid, $recipe_id)
	{
		global $DB, $L, $G;
		
		$recipe_id = (int)$recipe_id;
		$sql = 'SELECT * FROM make_recipe WHERE id='.$recipe_id;
		$recipe = $DB->getValue($sql);
		
		if ($uid != $recipe['uid']) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		$DB->beginTransaction();
		
		
		$sql = 'DELETE FROM make_recipe WHERE id='.$recipe_id;
		$ret = $DB->delete('make_recipe', 'id='.$recipe_id);
		
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('making_save_recipe', $str);
		}
		
		return $result;
	}
	
	/**
	 * 增加配方经验
	 * @param int $uid
	 * @param int $recipe_id
	 */
	public static function addRecipeExp($uid, $recipe_id)
	{
		global $DB, $L, $G;
		
		$recipe_id = (int)$recipe_id;
		
		$sql = 'SELECT * FROM make_recipe WHERE id='.$recipe_id;
		$recipe = $DB->getValue($sql);
		
		// 超过百分百就不用再增加经验
		if ($recipe['exp'] >= 10000) {
			return array(
				'val' => true,
				'addExp' => 0
			);
		}
		
		$cfg = $G['recipe'][$recipe['product_lvl']][$recipe['lvl']];
		$addExp = rand($cfg['make_get_exp'][0]*10000, $cfg['make_get_exp'][1]*10000);
		
		if (($recipe['exp'] + $addExp) > 10000) {
			$sql = 'UPDATE make_recipe SET exp=10000 WHERE id='.$recipe_id;
		} else {
			$sql = 'UPDATE make_recipe SET exp=exp+'.$addExp.' WHERE id='.$recipe_id;
		}
		$ret = $DB->exeSql($sql);
		
		if ($ret !== false) {
			$ret = true;
		}

		return array(
			'val' => (bool)$ret,
			'addExp' => $addExp
		);
	}
	
	/**
	 * 升级配方档次
	 * @param int $uid
	 * @param int $recipe_id
	 */
	public static function recipeLvlUp($uid, $recipe_id)
	{
		global $DB, $L, $G;
		
		$recipe_id = (int)$recipe_id;
		
		$sql = 'SELECT * FROM make_recipe WHERE id='.$recipe_id;
		$recipe = $DB->getValue($sql);
		// 不是自己的配方
		if ($recipe['uid'] != $uid) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		// 经验不足百分百(百分比保留两位小数,转成整数保存)
		if ($recipe['exp'] < 10000) {
			return array(
				'val' => false,
				'msg' => $L['recipe_exp_not_full']
			);
		}
		// 配方档次已达到最高
		if ($recipe['lvl'] >= $G['recipe_max_lvl']) {
			return array(
				'val' => false,
				'msg' => $L['recipe_is_max_lvl']
			);
		}
		
		// 金钱是否足够
		$cfg = $G['recipe'][$recipe['product_lvl']][$recipe['lvl']];
		$needCoin = $cfg['lvlup_coin'];
		$sql = 'SELECT coin FROM user WHERE uid='.$uid;
		$coin = $DB->getValue($sql);
		if ($needCoin > $coin) {
			return array(
				'val' => false,
				'msg' => $L['coin_not_enough']
			);
		}
		
		// 是否成功
		$success = getRandResult($cfg['lvlup_success'] * 100);
		
		$DB->beginTransaction();
		
		// 扣除金钱
		$sql = 'UPDATE user set coin=coin-'.$needCoin.' WHERE uid='.$uid;
		$ret = $DB->exeSql($sql);
		
		// 升级成功增加档次,并重置经验为0
		if ($success) {
			$sql = 'UPDATE make_recipe SET lvl=lvl+1,exp=0 WHERE id='.$recipe_id;
			$ret = $DB->exeSql($sql);
			$recipe['lvl']++;
			$recipe['exp'] = 0;
		}
		
		// 判断人气值是否需要更新
		if ($success && $ret) {
			$sql = 'SELECT pop_val FROM user_shop WHERE uid='.$uid;
			$pop_val = $DB->getValue($sql);
			$new_pop_val = self::getRecipeTotalPopVal($uid);
			if ($new_pop_val > $pop_val) {
				$sql = 'UPDATE user_shop SET pop_val='.$new_pop_val.' WHERE uid='.$uid;
				$ret = $DB->exeSql($sql);
			}
		}

		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			
			$itemList = C('item/item_list');
			
			$matIdList = array();
			
			$classSign = $G['make_class_type_sign_list'][$recipe['class']];
			$recipe['product']	= $G[$classSign][$recipe['product']]['title'];
			$recipe['technics']	= $G[$classSign.'_technics'][$recipe['technics']];
			$recipe['param']	= $G[$classSign.'_param'][$recipe['param']];
			
			$main_mat = json_decode($recipe['main_mat'], true) ;
			$sec_mat  = json_decode($recipe['sec_mat'], true) ;
			$recipe['main_mat'] = array();
			$recipe['sec_mat'] = array();
			foreach ($main_mat as $item_id => $num) {
				if (!in_array($item_id, $matIdList)) {
					$matIdList[] = $item_id;
				}
				$recipe['main_mat'][] = array(
					'item_id'	=> $item_id,
					'num'		=> $num,
					'title'		=> $itemList[$item_id]['title'],
				);
			}
			foreach ($sec_mat as $item_id => $num) {
				if (!in_array($item_id, $matIdList)) {
					$matIdList[] = $item_id;
				}
				$recipe['sec_mat'][] = array(
					'item_id'	=> $item_id,
					'num'		=> $num,
					'title'		=> $itemList[$item_id]['title'],
				);
			}
			
			// 判断材料是否足够
			// 从数据库获取主/辅材数量
			$sql = 'SELECT item_id,num,quality FROM depot WHERE uid='.$uid.' AND item_id in ('.join(',', $matIdList).')';
			$matList = $DB->getList($sql);
			$matList2 = array();
			foreach ($matList as $v) {
				$matList2[$v['item_id'].','.$v['quality']] = $v['num'];
			}
			
			if ($recipe['lvl'] > 3) {
				$quality = 3;
			} else {
				$quality = $recipe['lvl'];
			}
			foreach ($recipe['main_mat'] as $kk=>$vv) {
				$holdNum = $matList2[$vv['item_id'].','.$quality];
				if ($vv['num'] > $holdNum) {
					$recipe['main_mat'][$kk]['lack_num'] = $vv['num'] - $holdNum;
				} else {
					$recipe['main_mat'][$kk]['lack_num'] = 0;
				}
			}
			foreach ($recipe['sec_mat'] as $kk=>$vv) {
				$holdNum = $matList2[$vv['item_id'].','.$quality];
				if ($vv['num'] > $holdNum) {
					$recipe['sec_mat'][$kk]['lack_num'] = $vv['num'] - $holdNum;
				} else {
					$recipe['sec_mat'][$kk]['lack_num'] = 0;
				}
			}
			
			$result['data'] = array(
				'recipe'	=> $recipe,
				'success'	=> $success
			);
		} else {
			$DB->rollBack();
			$result['msg'] = $L['Failure'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('making_save_recipe', $str);
		}
		
		return $result;
		
	}
	
	/**
	 * 根据配方来制造
	 * @param int $uid
	 * @param int $recipe_id
	 */
	public static function makeByRecipe($uid, $recipe_id)
	{
		global $DB, $L, $G;
		
		$recipe_id = (int)$recipe_id;
		
		$sql = 'SELECT * FROM make_recipe WHERE id='.$recipe_id;
		$recipe = $DB->getValue($sql);
		if (!$recipe) {
			return array(
				'val' => false,
				'msg' => $L['recipe_is_not_exists']
			);
		}
		
		if ($recipe['uid'] != $uid) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		$recipe['main_mat'] = json_decode($recipe['main_mat'], true) ;
		$recipe['sec_mat']  = json_decode($recipe['sec_mat'], true) ;
		
		$matItemIdList = array();
		$matList = array_merge($recipe['main_mat'], $recipe['sec_mat']);
		foreach ($matList as $item_id) {
			$matItemIdList[] = $item_id;
		}
		
		//主材和辅材品质
		$quality = $G['recipe_quality'][$recipe['lvl']];
		
		$tmp = Depot::getList($uid, 0, null, 0, $matItemIdList, 'quality='.$quality);
		$list = array();
		foreach ($tmp['data']['list'] as $v) {
			$list[$v['item_id']] = array(
				'depot_id'	=> $v['depot_id'],
				'num'		=> $v['num'],
				'item_type'	=> $v['item_type'],
			);
		}
		
		
		$main_mat = array();
		$sec_mat = array();
		foreach ($matList as $item_id) {
			if (!isset($list[$item_id]) 
					|| ($list[$item_id]['item_type'] == 51 && $list[$item_id]['num'] < $G['sec_mat_num'])
					|| ($list[$item_id]['item_type'] != 51 && $list[$item_id]['num'] < $G['main_mat_num'])
			) {
				return array(
					'val' => false,
					'msg' => $L['item_not_enough'].var_export($tmp,true)
				);
			}
			if ($list[$item_id]['item_type'] == 51) {
				$sec_mat[] = $list[$item_id]['depot_id']; 
			} else {
				$main_mat[] = $list[$item_id]['depot_id']; 
			}
		}
		
		$DB->beginTransaction();
		
		$DB->setTransactionState(false);
		$makeResult = self::make(
				$uid, 
				$recipe['class'], 
				$recipe['product'], 
				$recipe['technics'], 
				$recipe['param'], 
				$main_mat, 
				$sec_mat,
				$recipe_id
			);
		$DB->setTransactionState(true);
		
		// 增加配方经验
		if ($makeResult['val']) {
			$ret = self::addRecipeExp($uid, $recipe_id);
			if ($ret['val']) {
				$DB->commit();
				$result = $makeResult;
				$result['data']['addExp'] = $ret['addExp'];
			} else {
				$DB->rollBack();
				$result['val'] = false;
				$result['msg'] = $L['add_recipe_exp_error'];
				$str = var_export($DB->errors, true);
				// 记录错误日志
				Log::save('making_make_by_recipe', $str);
			}
			return $result;
		} else {
			$DB->rollBack();
			return $makeResult;
		}
	}

	/**
	 * 制造产品
	 * @param int $uid
	 * @param string|int $class 类型:烹饪,饮品,酿酒...(cook,drink..)
	 * @param int $product 产品:面食,糕点...
	 * @param int $technics 工艺
	 * @param int $param 参数:火力,温度,酒精浓度
	 * @param array $main_mat 主材
	 * @param array $sec_mat 辅材
	 * @param array $recipe_id 根据配方进行制造,增加配方经验
	 */
	public static function make($uid, $class, $product, $technics, $param, $main_mat, $sec_mat)
	{
		global $DB, $L, $G;
		
		// 制造类型ID
		if (is_int($class) || ctype_digit($class)) {
			if (isset($G['make_class_type_sign_list'][$class])) {
				$classId = $class;
				$class = $G['make_class_type_sign_list'][$classId];
			} else {
				return array(
					'val' => false,
					'msg' => $L['product_type_not_exists']
				);
			}
		} else {
			if (isset($G['make_class_type_list'][$class])) {
				$classId = $G['make_class_type_list'][$class];
			} else {
				return array(
					'val' => false,
					'msg' => $L['product_type_not_exists']
				);
			}
		}
		
		C('making/'.$class.'_param');
		$itemList = C('item/item_list');
		$updateSql = array();
		
		if (!isset($G[$class][$product])) {
			return array(
				'val' => false,
				'msg' => $L['product_type_not_exists']
			);
		}
		
		if (!isset($G[$class.'_technics'][$technics])) {
			return array(
				'val' => false,
				'msg' => $L['technic_not_exists']
			);
		}
		
		if (!isset($G[$class.'_param'][$param])) {
			return array(
				'val' => false,
				'msg' => $L['param_not_exists']
			);
		}
		
		$info = self::getInfo($uid, $classId, false);
		
		// 制造产品
		$producCfg = $G[$class][$product];
		$producCfg['title'] = $producCfg['title'];
		$productId = array_search($producCfg['title'], $G[$class.'_param_list']);
		// 制造工艺
		$techName = $G[$class.'_technics'][$technics];
		$techId = array_search($techName, $G[$class.'_param_list']);
		// 其它参数:火力,温度...
		$paramName = $G[$class.'_param'][$param];
		$paramId = array_search($paramName, $G[$class.'_param_list']);
		
		$arr = array($productId, $techId, $paramId);
		
		$itemMat = C('making/'.$class.'_item_mat');
		
		$mainMatStr = '';
		// 每种主材的数量
		$mainMatNum = $G['main_mat_num'];
		foreach ($main_mat as $id) {
			if (!is_int_string($id)) {
				return array(
					'val' => false,
					'msg' => $L['invalid_main_mat_id']
				);
			}
			if (empty($mainMatStr)) {
				$mainMatStr = $id;
			} else {
				$mainMatStr .= ','.$id;
			}
			$updateSql[] = 'UPDATE depot SET num=num-'.$mainMatNum.' WHERE depot_id='.$id;
		}
		// 取主材的数据
		$sql = 'SELECT depot_id,uid,item_id,num,quality,lvl FROM depot WHERE depot_id in ('.$mainMatStr.')';
		$mainMatList = $DB->getList($sql);
		$mainMatQuality = 0;//主材品质
		if (!$mainMatList) {
			return array(
				'val' => false,
				'msg' => $L['main_mat_not_enough']
			);
		}
		// 制造的产品等级等于主材中最高的等级
		$productLvl = 0;
		//保存不同主材数量,用于计算最终产品的等级
		$mainItemIdList = array();
		// 所有主材总数量
		$mainItemNum = $G['main_mat_type_num'] * $G['main_mat_num'];
		$_tmpLvl = array();//主材不同等级的数量
		foreach ($mainMatList as $item) {
			$itemId = $item['item_id'];
			// 材料等级不能超出建筑等级
			if ($info['building_lvl'] < $item['lvl']) {
				return array(
					'val'	=> false,
					'msg'	=> $L['main_mat_lvl_higher_than_building_lvl']
				);
			}
			// 用户参数中消耗的主材数量
			if (isset($mainItemIdList[$itemId])) {
				$mainItemIdList[$itemId] += $G['main_mat_num'];
			} else {
				$mainItemIdList[$itemId] = $G['main_mat_num'];
			}
			// 主材是否属于当前玩家
			if ($item['uid'] != $uid) {
				return array(
					'val'	=> false,
					'msg'	=> $L['invalid_request']
				);
			}
			// 主材数量是否足够
			if ($G['main_mat_num'] > $item['num']) {
				return array(
					'val' => false,
					'msg' => $L['main_mat_not_enough']
				);
			}
			//不是当前制造产品的主材
			if ($itemId > 1000 || !isset($itemMat[$itemId])) {
				return array(
					'val' => false,
					'msg' => $L['item_is_not_main_mat']
				);
			}
			$itemLvl = $itemList[$itemId]['lvl'];
			$quality = $G['id_quality'][$item['quality']];
			$unitQuality = $G['main_mat_quality'][$itemLvl][$quality];
			$mainMatQuality += ($G['main_mat_num'] * $unitQuality);
			$arr[] = $itemMat[$itemId];
			
			if (!isset($_tmpLvl[$itemLvl])) {
				$_tmpLvl[$itemLvl] = 1;
			} else {
				$_tmpLvl[$itemLvl] += 1;
			}
		}
		// 主材种类数量限制
		if (count($mainItemIdList) != $G['main_mat_type_num']) {
			return array(
				'val' => false,
				'msg' => $L['main_mat_type_num_error']
			);
		}
		$maxNum = 0;
		
		// 主材料4种,有4个记录,说明4个材料的等级不同,取最高等级
		if (count($_tmpLvl) == $G['main_mat_type_num']) {
			ksort($_tmpLvl);
			$productLvl = end($_tmpLvl);
		} else {
			$num = 0;
			foreach ($_tmpLvl as $lvl=>$cnt) {
				if ($cnt > $num) {
					$productLvl = $lvl;
					$num = $cnt;
				} else if ($cnt == $num && $lvl > $productLvl) {
					$productLvl = $lvl;
				}
			}
		}
		
		$secMatStr = '';
		// 每种辅材的数量
		$secMatNum = $G['sec_mat_num'];
		foreach ($sec_mat as $id) {
			if (!is_int_string($id)) {
				return array(
					'val' => false,
					'msg' => $L['invalid_sec_mat_id']
				);
			}
			if (empty($secMatStr)) {
				$secMatStr = $id;
			} else {
				$secMatStr .= ','.$id;
			}
			$updateSql[] = 'UPDATE depot SET num=num-'.$secMatNum.' WHERE depot_id='.$id;
		}
		// 取辅材的数据
		$sql = 'SELECT depot_id,uid,item_id,num,quality FROM depot WHERE depot_id in ('.$secMatStr.')';
		$secMatList = $DB->getList($sql);
		$secMatQuality = 0;//辅材品质
		if (!$secMatList) {
			return array(
				'val' => false,
				'msg' => $L['sec_mat_not_enough']
			);
		}
		$secItemIdList = array();
		$secItemNum = $G['sec_mat_type_num'] * $G['sec_mat_num'];
		foreach ($secMatList as $item) {
			$itemId = $item['item_id'];
			if (isset($secItemIdList[$itemId])) {
				$secItemIdList[$itemId] += $G['sec_mat_num'];
			} else {
				$secItemIdList[$itemId] = $G['sec_mat_num'];
			}
			// 辅材是否属于当前玩家
			if ($item['uid'] != $uid) {
				return array(
					'val'	=> false,
					'msg'	=> $L['invalid_request']
				);
			}
			// 辅材数量是否足够
			if ($G['sec_mat_num'] > $item['num']) {
				return array(
					'val' => false,
					'msg' => $L['sec_mat_not_enough'].$item['num']
				);
			}
			if (!isset($itemMat[$itemId])) {
				return array(
					'val' => false,
					'msg' => $L['item_is_not_sec_mat']
				);
			}
			$unitQuality = $G['se_mat_quality'][$item['quality']];
			$secMatQuality += ($G['sec_mat_num'] * $unitQuality);
			$arr[] = $itemMat[$itemId];
			// 判断物品是否辅材
			if (!isset($G[$class.'_sec_mat_item'][$itemId])) {
				return array(
					'val' => false,
					'msg' => $L['item_is_not_sec_mat']
				);
			}
		}
		// 辅材种类数量限制
		if (count($secItemIdList) != $G['sec_mat_type_num']) {
			return array(
				'val' => false,
				'msg' => $L['sec_mat_type_num_error']
			);
		}
		
		sort($arr);
		
		// 获取玩家所使用的配方参数模板
		$sql = 'SELECT making_recipe FROM user WHERE uid='.$uid;
		$recipe_no = $DB->getValue($sql);
		
		// 参数加成=参数表中两两对应的数值乘积
		$paramAddition = 1;
		/*
		 * 从配方模板表中查询参数值,统一取所有配置再整合成配置数组,
		 * 避免多次循环获取需要太多的sql查询
		 */
		$sql = 'SELECT x_y,val FROM tpl_recipe_'.$class.' WHERE recipe_no='.$recipe_no;
		$reList = $DB->getList($sql);
		$recipeList = array();
		foreach ($reList as $v) {
			$recipeList[$v['x_y']] = $v['val'];
		}
		foreach ($arr as $k => $v) {
			foreach ($arr as $kk => $vv) {
				if ($kk < $k) {
					continue;
				}
				$match_key_1 = $v.'-'.$vv;
				$match_key_2 = $vv.'-'.$v;
				if (isset($recipeList[$match_key_1])) {
					$cfg_val = $recipeList[$match_key_1];
				} else {
					$cfg_val = $recipeList[$match_key_2];
				}
				$paramAddition *= ($cfg_val/1000);
			};
		}
		
		$staffData = Staff::getData($uid, $class, $producCfg['item_id']);
		// 最终品质
		$resQuality = round($mainMatQuality * $paramAddition + $staffData['abi_val'] + $secMatQuality) 
						+ rand($G['make_rand_add_val'][0], $G['make_rand_add_val'][1]);
		
		$DB->beginTransaction();
		
		// 扣除材料
		$sql = join(";\n", $updateSql);
		$ret = $DB->exeSql($sql);
		
		// exeSql只有返回值全等于false时才为处理失败
		$ret!==false && $ret = true;
		
		// 增加建筑经验
		$maxExp = $G['make_building_lvlup_exp'][$info['building_lvl']];
		if ($ret && $info['exp'] < $maxExp) {
			$exp = $G['make_get_exp_param'][0] * $mainItemNum 
					+ ($mainItemNum-$G['make_get_exp_param'][1]) * $G['make_get_exp_param'][2];
			if (($info['exp'] + $exp) > $maxExp) {
				$sql = 'UPDATE make_building SET exp='.$maxExp.' WHERE uid='.$uid.' AND class='.$classId;
			} else {
				$sql = 'UPDATE make_building SET exp=exp+'.$exp.' WHERE uid='.$uid.' AND class='.$classId;
			}
			$ret = $DB->exeSql($sql);
			if ($ret !== false) {
				$ret = true;
			}
		}
		
		// 增加员工潜力经验
		if ($ret) {
			C('making/staff');
			$sql = 'SELECT * FROM staff WHERE uid='.$uid.' and class=:class';
			$param = array('class' => $classId);
			$staff = $DB->getValue($sql, $param);
			if ($staff['potential_lvl'] == 0 && $resQuality <$G['potential_lvl_list'][0]['min_quality']) {
				// 0级时,假设有-1级,且最低品质要求为0
				$G['potential_lvl_list'][-1]['min_quality'] = 0;
			}
			if ($resQuality > $G['potential_lvl_list'][$staff['potential_lvl']]['min_quality']) {
				$exp = round($resQuality/100);
			} else if ($resQuality > $G['potential_lvl_list'][$staff['potential_lvl']-1]['min_quality']) {
				$exp = round($resQuality/200);
			} else {
				$exp = 0;
			}
			if ($exp > 0) {
				$ret = Staff::addPotentialExp($staff['staff_id'], $exp);
				if ($ret !== false) {
					$ret = true;
				}
			}
		}
		
		//增加培训点
//		if ($ret) {
//			$staff_id = $staff['staff_id'];
//			$point_num = $staff['lvl'];
//			$ret = Staff::addTrainPoint($staff_id, $point_num);
//		}
		
		if ($ret) {
			$data = array(
				'item_id'	=> $producCfg['item_id'],
				'title'		=> $producCfg['title'],
				'item_type'	=> $producCfg['item_type'],
				'num'		=> 1,
				'stack'		=> 0,
				'quality'	=> $resQuality,
				'main_mat_quality' => $mainMatQuality,
				'lvl'		=> $productLvl,
			);
			$return = Shop::depotIn($uid, $data);
			$ret = $return['val'];
			$result['msg'] = $return['msg'];
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				'depot_id'	=> $return['data']['depot_id'],
				'item_id'	=> $producCfg['item_id'],
				'lvl'		=> $productLvl,
				'quality'	=> $resQuality,
			);
		} else {
			$DB->rollBack();
			isset($result['msg']) || $result['msg'] = $L['Failure'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('making_make', $str);
		}
		return $result;
	}
	
	/**
	 * 提交比赛的产品
	 * @param unknown_type $uid
	 * @param unknown_type $product_id
	 */
	public static function submitPkProduct($uid, $product_id)
	{
		global $DB, $L, $G;
		
		$today = strtotime('today');
		$nowHour = date('H');
		
		// 非比赛时间
		if ($nowHour < $G['product_pk_time']['start_time'] && $nowHour > $G['product_pk_time']['end_time']) {
			return array(
				'val'	=> false,
				'msg'	=> $L['is_not_in_compete_time']
			);
		}
		
		// 当天已提交产品,不能再参与
		$sql = 'SELECT id FROM make_product_compete WHERE uid='.$uid.' AND compete_date='.$today;
		$exist = $DB->getValue($sql);
		if ($exist) {
			return array(
				'val'	=> false,
				'msg'	=> $L['today_had_in_compete']
			);
		}
		
		$sql = 'SELECT * FROM shop_depot WHERE depot_id='.$product_id;
		$productInfo = $DB->getValue($sql);
		
		// 比赛类型
		if (Game::$data['today_pk_product_class'] != $productInfo['item_type']) {
			return array(
				'val'	=> false,
				'msg'	=> $L['is_not_in_compete_class']
			);
		}
		// 小类型不匹配
		if (Game::$data['today_pk_product_item_id'] != $productInfo['item_id']) {
			return array(
				'val'	=> false,
				'msg'	=> $L['is_not_in_compete_type']
			);
		}
		
		$DB->beginTransaction();
		
		$data = array(
			'uid'		=> $uid,
			'nickname'	=> $_SESSION['nickname'],
			'title'		=> $productInfo['title'],
			'quality'	=> $productInfo['quality'],
			'lvl'		=> $productInfo['lvl'],
			'compete_date'	=> $today,
		);
		$ret = $DB->insert('make_product_compete', $data);
		
		// 从店铺仓库删除物品
		if ($ret) {
			$sql = 'DELETE FROM shop_depot WHERE depot_id='.$product_id;
			$ret = $DB->delete('shop_depot', 'depot_id='.$product_id);
		}
		
		// 获得金钱
		if ($ret) {
			$coin = $productInfo['quality'] * 1.5;
			$sql = 'UPDATE user SET coin=coin+'.$coin.' WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
		}
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data'] = array(
				'coin'	=> $coin
			);
		} else {
			$DB->rollBack();
			isset($result['msg']) || $result['msg'] = $L['Failure'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('making_submit_pk_product', $str);
		}
		return $result;
	}
	
	/**
	 * 获取产品比赛结果的排名TOP100
	 * @param $uid
	 */
	public static function getTopList($uid, $lvl)
	{
		global $DB, $L, $G;
		
		$nowHour = date('H');
		// 未到公布结果的时间
//		if ($nowHour >= $G['product_pk_time']['clear_time'] && $nowHour <= $G['product_pk_time']['result_time']) {
//			return array(
//				'val'	=> false,
//				'msg'	=> $L['is_not_end_compete_time']
//			);
//		}
		
		$compete_date = strtotime('today');
		$sql = 'SELECT uid,nickname,quality FROM make_product_compete 
				WHERE compete_date='.$compete_date.' AND lvl='.$lvl
				.' ORDER BY quality DESC LIMIT 0,100';
		$list = $DB->getList($sql);
		
		return array(
			'val' => true,
			'data' => $list,
		);
	}
	
	/**
	 * 计算PK奖励结果
	 * @param int $uid
	 */
	public static function calcPkResult($uid)
	{
		global $DB, $L, $G;
		
		$nowHour = date('H');
		// 未结束
		if ($nowHour >= $G['product_pk_time']['start_time'] && $nowHour <= $G['product_pk_time']['end_time']) {
			return array(
				'val'	=> false,
				'msg'	=> $L['is_not_end_compete_time']
			);
		}
		
		// 获取当前用户最近一次参加比赛数据
		$sql = 'SELECT id,compete_date,lvl FROM make_product_compete WHERE uid='.$uid
				.' ORDER BY compete_date DESC';
		$record = $DB->getValue($sql);
		if (!$record) {
			return false;
		}
		
		// 取出指定日期前一百名的数据
		$sql = 'SELECT id,uid FROM make_product_compete 
				WHERE compete_date='.$record['compete_date'].' AND lvl='.$record['lvl']
				.' ORDER BY quality DESC LIMIT 0,100';
		$list = $DB->getList($sql);
		$order = 0;
		$inTop = false;
		foreach ($list as $v) {
			$order++;
			if ($v['uid'] == $uid ) {
				$inTop = true;
				break;
			}
		}
		
		// 前一百名
		if ($inTop) {
			$item_id = getRangeKeyValue($order, $G['product_pk_prize'], 'gt');
		} else {
			$item_id = getRangeKeyValue(101, $G['product_pk_prize'], 'gt');
		}
		
		
		$DB->beginTransaction();
		
		$data = array(
			'prize_item_id' => $item_id
		);
		$ret = $DB->update('make_product_compete', $data, 'id='.$record['id']);
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			$DB->commit();
			$result['data']['order'] = $order;
		} else {
			$DB->rollBack();
			isset($result['msg']) || $result['msg'] = $L['Failure'];
			$str = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('making_calc_pk_result', $str);
		}
		return $result;
	}
	
	/**
	 * 获取产品PK信息
	 * @param int $uid
	 */
	public static function getProductPkInfo($uid) 
	{
		global $DB, $G;
		$itemList = C('item/item_list');
		$itemCfg = $itemList[Game::$data['today_pk_product_item_id']];
		// 当天是否已提交产品
		$today = strtotime('today');
		$sql = 'SELECT id,quality,lvl,ranking FROM make_product_compete WHERE uid='.$uid.' AND compete_date='.$today;
		$exist = $DB->getValue($sql);
		$prizeItemCfg = $itemList[$exist['prize_item_id']];
		return array(
			'val'	=> true,
			'data'	=> array(
				'class'				=> Game::$data['today_pk_product_class'],
				'item_id'			=> Game::$data['today_pk_product_item_id'],
				'class_title'		=> $G['make_class_type_name_list'][Game::$data['today_pk_product_class']],
				'item_title'		=> $itemCfg['title'],
				'item_type'			=> $itemCfg['type'],
				'submit_today'		=> $exist ? true : false,
				'quality'			=> $exist['quality'],
				'lvl'				=> $exist['lvl'],
				'ranking'			=> $exist['ranking'],
				'prize_item_id'		=> $exist['prize_item_id'],
				'prize_item_title'	=> $prizeItemCfg['title'],
			),
		);
	}
}





